/*
 * chapter_14.cpp
 * 第14章：重载运算与类型转换
 *  Created on: 2020年12月3日
 *      Author: san
 */

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <functional>

#include "String.h"
#include "StrVec.h"
#include "Sales_data.h"
#include "StrBlobPtr.h"
#include "ITESympol.h"
#include "IsEqual.h"
#include "StringCount.h"

void t14_7()
{
	String s1("hello world!");
	std::cout << s1;
}

void t14_11()
{
	Sales_data sd1;
	std::cout << "请输入 bookNo, units_sold, prrice: ";
	std::cin >> sd1;
	std::cout << sd1;
}

void t14_26()
{
	StrVec sv1;
	sv1.push_back("hello world!");
	sv1.push_back("hello c!");
	sv1.push_back("hello cpp!");
	std::vector<int> ivec{ 1, 3, 5, 7, 9 };

}

void t14_30()
{
	StrBlob sb1 = {"how's the weather?", "today is sunny" };
	StrBlobPtr p(sb1);
	*p++ = "okay";
	*p = "hello";

	std::cout << "p中首元素的大小p->size()： " << p->size() << std::endl;
	std::cout << "p中首元素的大小p->size()： " << (*p).size() << std::endl;  // 两式等价
}

void t14_32()
{
	//
}

void t14_34()
{
	// if-then-else
	ITESympol ite;
	std::string res = ite(false);
	std::cout << res;
}

void t14_37()
{
	// 判断两个string是否相等
	std::string s1("hello");
	std::string s2("hello");
	IsEqual is_equal;
	std::cout << is_equal(s1, s2) << std::endl;
}

void t14_38()
{
	// 统计长度为n的单词的个数
	StringCount sc;
	std::ifstream in("/home/san/eclipse-workspace/CppPrimer/file/strcount.txt");
	std::map<std::size_t, std::size_t> sc_map;
	std::string word;

	while (in >> word)
	{
		std::size_t count = sc(word);
		++sc_map[count];
	}

	std::for_each(sc_map.begin(),sc_map.end(), [](const std::pair<std::size_t, std::size_t> &p){
		std::cout << p.first << ": " << p.second << std::endl;});
}

void t14_43()
{
	// 使用标准库函数对象判断一个给定的int能否被int容器中的所有元素整除
	std::vector<int> ivec{1,3,5,7,9};
	int num = 1 * 3 * 5 * 7 * 9 + 1;
	bool flag = true;
	std::for_each(ivec.begin(), ivec.end(), [&](const int &i){ if (0 != num % i) flag = false; });
	if (flag)
		std::cout << "num: " << num << "能被容器ivec中的所有元素整除" << std::endl;
	else
		std::cout << "不能";
}

int add(int a, int b) { return a + b; }
auto mod = [](const int &a, const int &b) { return a % b; };


void t14_44()
{
//	int add(int a, int b) { return a + b; }
//	auto mod = [](const int &a, const int &b) { return a % b; };
	struct divide
	{
		int operator() (int a, int b) { return a / b; };
	};

	std::map<std::string, std::function<int(int, int)> > funcs = {
			{"+", add},
			{"-", std::minus<int>()},
			{"*", [](int a, int b){ return a * b; }},
			{"/", divide()},
			{"%", mod}
	};

	std::string first, op, second;
	while (std::cin >> first >> op >> second && "0" != first)
	{
		if (std::cin)
		{

			std::cout << funcs[op](std::stoi(first), std::stoi(second));
		}
	}
}

void t14_45()
{
	Sales_data sd1("Y001");
	std::cout << string(sd1) << std::endl;
}

int main14()
{
	std::cout << "----------------输入输出运算符--------------------" << std::endl;
//	t14_7();
//	t14_11();

	std::cout << "-----------------自增自减运算符-------------------" << std::endl;
	t14_26();
	t14_30();

	std::cout << "-----------------函数调用运算符-------------------" << std::endl;
	t14_34();
	std::cout << std::endl;
	t14_37();

	std::cout << "-----------------标准库定义的函数对象-------------------" << std::endl;
	t14_38();
	t14_43();

	std::cout << "-----------------可调用对象与function-------------------" << std::endl;
//	t14_44(); // 有cin

	std::cout << "-----------------重载、类型转换与运算符-------------------" << std::endl;
	t14_45();

	return 0;
}



